package de.fuberlin.inf.alp2;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;


/**
 * This class will print out all primes less or equal a specified integer.
 * @author	Stefan Rolfs
 */
public class Primes {

	/**
	 * @param	args	If first argument contains an integer, it will be used
	 * 					as max. Otherwise the program will ask you to type in
	 * 					the value again.
	 */
	public static void main(String[] args) {
		final int MAX;
		int[] primes;

		MAX = Primes.getMaxValue(args);
		primes = Primes.getPrimesArray(MAX);
		int len = primes.length;
		
		for (int i = 0; i < len; i++)
			System.out.print(primes[i] + " ");
	} // main
	
	/**
	 * This method will use the first parameter to convert it to int. If this is
	 * not possible, it requests an input by the user, until the entered string
	 * has been successfully converted to int.
	 * @param	args	If first argument contains an integer, it will be used
	 * 					as max. Otherwise the program will ask to type in
	 * 					the value again.
	 * @return 			The int value of the passed string.
	 */
	private static int getMaxValue(String[] args) {
		int max = 0;
		boolean readMaxValue = true;
		
		if (args.length > 0) {
			// If the max value is passed with the program arguments, take it
			try {
				max = Integer.parseInt(args[0]);
				readMaxValue = false;
			}
			catch (NumberFormatException exc) {
				System.out.println("Sie sollten eine ganze Zahl eingeben.");
			}
		} // args.length > 0
		
		// Otherwise request input
		if (readMaxValue) {
			BufferedReader console = new BufferedReader(new InputStreamReader(System.in));
		
			while (readMaxValue) {
				System.out.print("\nGeben sie den Maximalwert an!\nMAX = ");
				try {
					String inputString = console.readLine();
					max = Integer.parseInt(inputString);
					readMaxValue = false;
					console.close();
				}
				catch (IOException exc) {
					exc.printStackTrace();
				}
				catch (NumberFormatException exc) {
					readMaxValue = true;
					System.out.println("Sie sollten eine ganze Zahl eingeben.");
				}
			}
		} // request input
		
		return max;
	} // getMaxValue
	
	/**
	 * This method will return an array containing all primes less or equal the
	 * passed argument <code>MAX</code>.
	 * @param	MAX			The upper limit of primes.
	 * @return	The array consisting all primes less or equal the
	 * passed argument <code>MAX</code>.
	 */
	private static int[] getPrimesArray(final int MAX) {
		int i, j;
		int countPrimes = MAX / 2;
		int[] returnValue;
		boolean[] isPrime = new boolean[MAX + 1];
		
		if (MAX < 2)
			return new int[0];
		
		for (j = 3; j <= MAX; j = j+2)
			isPrime[j] = true;

		isPrime[2] = true;
		
		i = 3;
		while (i <= MAX) {
			for (j = 3; j <= (i / 2); j++)
				if (isPrime[j] && (i % j) == 0) {
					isPrime[i] = false;
					countPrimes--;
					break;
				}
			i = i + 2;
		}
		
		returnValue = new int[countPrimes];
		j = 0;
		for (i = 2; i <= MAX; i++)
			if (isPrime[i])
				returnValue[j++] = i;
		return returnValue;
	} // getPrimesArray
} // class